﻿using AuthorizationApiSample.Data;
using AuthorizationApiSample.Data.Entities;
using AuthorizationApiSample.Handlers;
using AuthorizationApiSample.Options;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace AuthorizationApiSample
{
    public static partial class Extensions
    {
        /// <summary>
        /// 添加身份服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddIdentity(this IServiceCollection services)
        {
            services.AddIdentity<UserEntity, RoleEntity>(options =>
            {
                #region 密码策略
                options.Password.RequireDigit = false;
                options.Password.RequireLowercase = false;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                #endregion
                options.Lockout.AllowedForNewUsers = false;//新用户锁定
                options.User.RequireUniqueEmail = false;//邮箱是否重复
                options.Lockout.MaxFailedAccessAttempts = 3;//密码错误次数锁定
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(1);//锁定时间
            })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
            return services;
        }

        /// <summary>
        /// 添加JWT认证服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddJwtAuthentication(this IServiceCollection services)
        {
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,//是否验证Issuer
                    ValidateAudience = false,//是否验证Audience
                    ValidateLifetime = true,//是否验证超时  当设置exp和nbf时有效 
                    ValidateIssuerSigningKey = true,  //是否验证密钥
                    ValidIssuer = "http://localhost:5000",//需要与登陆时颁发的一致
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("123456789123456789")),
                    ClockSkew = TimeSpan.FromMinutes(1)//设置过期时间
                };
            });
            return services;
        }

        /// <summary>
        /// 添加策略授权服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddPolicyAuthorization(this IServiceCollection services)
        {
            //策略结合声明授权
            services.AddAuthorization(options =>
            {
                options.AddPolicy("RolePermissionsPolicy", policy => policy.AddRequirements(new RolePermissionsRequirement()));
            });
            services.AddSingleton<IAuthorizationHandler, RolePermissionsHandler>();
            return services;
        }

    }
}
